<template>
  <el-dialog
    title="订单行程"
    :visible.sync="dialogVisible"
    width="65%"
    class="common-dialog"
    top="10vh"
  >
    {{routeData.loading}}
    <el-form
      v-loading="routeData.loading"
      label-width="83px"
      label-suffix="："
    >
      <el-form-item label="起点">{{routeData.start}}</el-form-item>
      <el-form-item label="终点">{{routeData.end}}</el-form-item>
      <el-form-item label="行驶路线"></el-form-item>
      <div id="map"></div>
    </el-form>
    <div slot="footer" class="dialog-footer">

    </div>
  </el-dialog>
</template>

<script>
  /**
   * @Author: lifuzhao
   * @Date: 2019-07-28
   * @Project: driver
   */
  import {throttle} from 'lodash'
  import {mapState} from 'vuex'

  let timers = {}
  export default {
    name: "route"
    , data() {
      return {
        dialogVisible: false
        , order: {}
        , mapInstance: null
        , size: 200
        , lineArr: []
        , passedMarkerIndex: 0
        , passedMarkerArr: []
      }
    }
    , computed: {
      ...mapState([
        'orderRouteData'
      ])
      , routeData() {
        let order = this.order
          , orderRouteData = this.orderRouteData
        return orderRouteData[order.id] || {}
      }
      , loading() {
        return this.routeData.loading
      }
      , loadEnd() {
        return this.routeData && this.routeData.loadEnd
      }
    }
    , watch: {
      routeData: {
        deep: true
        , handler(routeData) {
          if (!routeData.locations || routeData.locations.length === 0) {
            return
          }
          this.renderMap()
        }
      }
      , dialogVisible(bool) {
        if (!bool) {
          Object.keys(timers).forEach(timer => {
            clearTimeout(parseInt(timer))
          })
          this.mapInstance && this.mapInstance.destroy()
          this.mapInstance = null
          this.polyline = null
          this.passedPolyline = null
          this.marker = null
        }
        this.$fn.setTitle(bool ? '订单行程' : '订单记录')
      }
    }
    , mounted() {
      this.init()
    }
    , methods: {
      init() {
        this.$bus.$on('viewOrderRoute', order => {
          this.dialogVisible = true
          this.order = order
          let routeData = this.routeData
          this.updateRouteData({
            order: order
            , page: 1
            , data: {
              loading: Object.keys(routeData).length === 0
              , ...routeData
            }
          })
          this.getRouteApi({
            order: order
            , page: 1
            , size: this.size
            , quick: false
          })
        })
      }
      , getRouteApi({order = {}, page = 1, size = this.size, quick = false}) {
        clearTimeout(timers[order.id])
        return this.$axios.get('/api/v1/order/locations', {
          params: {
            id: order.id
            , page: page
            , size: size
          }
        })
          .then(res => {
            this.updateRouteData({
              order: order
              , page: page
              , data: {
                loading: false
                , ...res
              }
              , quick: quick
            })
          })
          .catch(() => {
            this.$alert('获取订单行程失败', '失败提示')
          })
      }
      , async updateRouteData({order = {}, data = {}, quick = false}) {
        let orderRouteData = this.$fn.deepClone(this.orderRouteData)
        orderRouteData[order.id] = orderRouteData[order.id] || {}
        orderRouteData[order.id].locations = orderRouteData[order.id].locations || []
        let state = data.state
          , start = data.start
          , end = data.end
          , {current_page = 1, last_page = 1, total = 0, data: originLocation = []} = data.locations || {}
        let convertLocation = [],
          promises = [],
          originLen = originLocation.length
        for (let i = 0; i < originLen; i = i + 40) {
          let start = i,
            end = start + 40
          let convert = originLocation.slice(start, end).map(item => [item.lng, item.lat])
          promises.push(new Promise((resolve, reject) => {
            // eslint-disable-next-line
            AMap.convertFrom(convert, 'baidu', (status, result) => {
              if (result.info === 'ok') {
                resolve(result.locations.map(locationItem => {
                  return [
                    locationItem.lng
                    , locationItem.lat
                  ]
                }))
              } else {
                reject()
              }
            })
          }))
        }
        let flag = true
        await Promise.all(promises).then(results => {
          results.forEach(result => {
            convertLocation = convertLocation.concat(result)
          })
        })
          .catch(() => {
            convertLocation = []
            flag = false
          })
        if (!flag) {
          this.$message('转换坐标失败，请退出重试')
          return
        }
        orderRouteData[order.id].locations[current_page - 1] = convertLocation
        orderRouteData[order.id].start = start
        orderRouteData[order.id].end = end
        orderRouteData[order.id].total = total
        orderRouteData[order.id].loadEnd = current_page === last_page
        this.$store.commit('setOrderRouteData', orderRouteData)
        if (!quick) {
          let promise = []
          for (let i = 2; i <= last_page; i++) {
            if (promise.length >= 5) {
              await Promise.all(promise)
            }
            promise.push(this.getRouteApi({
              order: order
              , page: i
              , quick: true
            }))
          }
        }
        if (state === 2) {
          let page = originLen === this.size ? current_page + 1 : current_page
          timers[order.id] = setTimeout(() => {
            this.getRouteApi({
              order: order
              , page: page
            })
          }, 5000)
        } else {
          clearTimeout(timers[order.id])
        }
      }
      , async renderMap() {
        let locations = this.routeData.locations
        let lineArr = []
        locations.forEach(item => {
          lineArr = lineArr.concat(item)
        })
        this.lineArr = lineArr
        let center = lineArr[lineArr.length - 1]
        if (!this.mapInstance) {
          // eslint-disable-next-line
          this.mapInstance = new AMap.Map('map', {
            resizeEnable: true
            , zoom: 16
            , center: center
          })
        } else {
          this.mapInstance.setCenter(center)
        }

        // eslint-disable-next-line
        this.polyline = new AMap.Polyline({
          map: this.mapInstance,
          path: lineArr,
          showDir: true,
          strokeColor: "#28F",  //线颜色
          strokeWeight: 6,      //线宽
        });
        // eslint-disable-next-line
        this.passedPolyline = new AMap.Polyline({
          map: this.mapInstance,
          strokeColor: "#AF5",  //线颜色
          // strokeOpacity: 1,     //线透明度
          strokeWeight: 6,      //线宽
          // strokeStyle: "solid"  //线样式
        })
        if (lineArr.length === 0) return
        if (!this.marker) {
          // eslint-disable-next-line
          this.marker = new AMap.Marker({
            map: this.mapInstance
            , position: lineArr[0]
            , icon: '/car.png'
            // eslint-disable-next-line
            , offset: new AMap.Pixel(-26, -13)
            , autoRotation: true
            , angle: -90
          })
          let c
          let throttleCb = throttle(() => {
            if (!c) return
            this.mapInstance.setCenter(c)
          }, 500)
          this.marker.on('moving', e => {
            if (this.movingTimer) {
              clearTimeout(this.movingTimer)
            }
            let passedPath = e.passedPath,
              passedMarkerIndex = this.passedMarkerIndex
            let passedMarkerArr = this.passedMarkerArr
            passedMarkerArr = [
              ...passedMarkerArr.slice(0, passedMarkerIndex),
              ...passedPath
            ]
            c = passedMarkerArr[passedMarkerArr.length - 1]
            throttleCb()
            this.passedMarkerArr = passedMarkerArr
            this.passedPolyline.setPath(passedMarkerArr)
            if (this.lineArr.length === this.passedLineIndex) return
            this.movingTimer = setTimeout(() => {
              this.passedMarkerIndex = passedMarkerArr.length
              this.marker.moveAlong(this.lineArr.slice(this.passedLineIndex), 1000)
              this.passedLineIndex = this.lineArr.length
            }, 200)
          })
          this.passedLineIndex = lineArr.length
          this.marker.moveAlong(lineArr, 800)
        }

      }
    }
  }
</script>

<style lang="less">
  .el-form-item {

  }
</style>
